package org.peoplesearch.idfilter;


import com.perm.kate.api.User;
import org.peoplesearch.vk.executor.VkAPiExecutor;
import org.peoplesearch.vk.executor.VkCommand;

import java.util.*;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

public class CityAgeFilter implements Filter {

    private Integer startAge;
    private Integer stopAge;
    private Integer city;
    private Integer sex;

    private VkAPiExecutor vkAPiExecutor;


    public CityAgeFilter(VkAPiExecutor vkAPiExecutor) {
        this.vkAPiExecutor = vkAPiExecutor;
    }

    public void setStartAge(Integer startAge) {
        this.startAge = startAge;
    }

    public void setStopAge(Integer stopAge) {
        this.stopAge = stopAge;
    }

    public void setCity(Integer city) {
        this.city = city;
    }

    public void setSex(Integer sex) {
        this.sex = sex;
    }

    public String getName() {
        return "CityAgeFilter_" + startAge + "_" + city;
    }

    public Map<Long, Boolean> match(Collection<Long> ids) {
        ArrayList<User> users = getUsers(ids);
        Map<Long, Boolean> result = new HashMap<Long, Boolean>();
        for (User user : users) {
            result.put(user.uid, match(user));
        }
        return result;
    }

    private ArrayList<User> getUsers(final Collection<Long> ids) {
        final ArrayList<User>[] users = new ArrayList[1];
        final CountDownLatch latch = new CountDownLatch(1);
        vkAPiExecutor.addCommand(new VkCommand() {
            @Override
            public void run() {
                try {
                    users[0] = api.getProfiles(ids, null, null, null, null, null);
                    latch.countDown();
                } catch (Exception e) {
                    e.printStackTrace();
                    throw new RuntimeException(e);
                }

            }
        });
        try {
            if (latch.await(3, TimeUnit.MINUTES)) {
                return users[0];
            } else {
                throw new RuntimeException("Can't get users");
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public boolean match(final Long id) {
        ArrayList<User> users = getUsers(Collections.singleton(id));
        if (match(users.get(0))) {
            return true;
        }
        return false;

    }

    private boolean match(User user) {
        if ((user.city == null)
                || ("".equals(user.city))
                || (user.graduation == null)
                || (user.graduation < 1950)
                || (user.graduation > 2100)) {
            return false;
        }
        return user.city.equals(city)
                && getAge(user) >= startAge
                && getAge(user) <= stopAge
                && user.sex.equals(sex);
    }

    private int getAge(User user) {
        if (user.graduation != null) {
            return (Calendar.getInstance().get(Calendar.YEAR) - (user.graduation - 5 - 18));
        }
        return -1;
    }

}
